import { ElMessage } from 'element-plus'
import { wsUrl, getCookie } from "@/utils/index"
import { useSystemNotificationStore } from '@/stores/systemNotification'

// WebSocket连接状态枚举
export enum WsResponseType {
  // 连接相关
  CONNECTION_SUCCESS = 'connection_success',
  CONNECTION_ERROR = 'connection_error',
  
  // 错误相关
  ERROR = 'error',
  
  // 私聊消息相关
  PRIVATE_MESSAGE = 'private_message',
  PRIVATE_MESSAGE_SEND_SUCCESS = 'private_message_send_message',
  PRIVATE_MESSAGE_READ_SUCCESS = 'private_message_read_success',
  
  // 系统通知相关
  SYSTEM_NOTIFICATION = 'system_notification',
  SYSTEM_NOTIFICATION_READ_SUCCESS = 'system_notification_read_success'
}

// WebSocket请求类型枚举
export enum WsRequestType {
  // 私聊消息相关
  PRIVATE_MESSAGE = 'private_message',
  PRIVATE_MESSAGE_READ = 'private_message_read',

  // 系统通知相关
  SYSTEM_NOTIFICATION_READ = 'system_notification_read'
}

// 系统通知类型
export interface SystemNotification {
  notification_id: number
  title: string
  content: string
  type: string
  priority: string
  is_sent: boolean
  receive_users: Record<number, { read: boolean }> | null
  createdAt: string
  updatedAt: string
}

// WebSocket工具类
class WebSocketManager {
  private socket: WebSocket | null = null
  private static instance: WebSocketManager
  private messageCallback: Function | null = null
  private userId: number | null = null
  private connectSuccessCallback: Function | null = null
  private connectErrorCallback: Function | null = null
  private reconnectTimer: NodeJS.Timeout | null = null
  private reconnectAttempts: number = 0
  private maxReconnectAttempts: number = 5
  private isManualClose: boolean = false // 添加手动关闭标志

  // 单例模式
  public static getInstance(): WebSocketManager {
    if (!WebSocketManager.instance) {
      WebSocketManager.instance = new WebSocketManager()
    }
    return WebSocketManager.instance
  }

  constructor() {}

  // 初始化WebSocket连接
  public init(
    onMessage: Function,
    onSuccess?: Function,
    onError?: Function
  ): boolean {
    // 从本地存储获取用户信息
    const userStr = localStorage.getItem('user')
    if (!userStr) {
      console.log('[WebSocket] 未登录用户，无法建立连接')
      this.close() // 关闭连接
      return false // 返回连接失败
    }
    
    let userInfo: any
    try {
      userInfo = JSON.parse(userStr)
    } catch (e) {
      console.log('[WebSocket] 用户信息解析失败，无法建立连接')
      this.close()
      return false
    }

    const userId = userInfo.user_id
    
    // 获取token用于认证
    const token = getCookie('token')
    if (!token) {
      console.log('[WebSocket] 缺少认证token，无法建立连接')
      this.close()
      return false
    }
    
    // 如果已经连接并且是同一个用户，不需要重新连接
    if (this.socket && this.userId === userId) {
      // 检查连接状态
      if (this.isConnected()) {
        this.messageCallback = onMessage
        if (onSuccess) onSuccess()
        return true
      }
    }
    
    this.userId = userId
    this.messageCallback = onMessage
    this.connectSuccessCallback = onSuccess || null
    this.connectErrorCallback = onError || null
    this.isManualClose = false // 重置手动关闭标志
    
    // 清除之前的重连定时器
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
    
    // 创建WebSocket连接，添加token参数用于认证
    this.socket = new WebSocket(`${wsUrl}?userId=${userId}&token=${token}`)
    
    this.socket.onopen = () => {
      if (this.connectSuccessCallback) {
        this.connectSuccessCallback()
      }
    }
    
    this.socket.onmessage = (event: MessageEvent) => {
      try {
        const data = JSON.parse(event.data)
        console.log('[WebSocket] 响应:', data)
        this.handleMessage(data)
      } catch (e) {
        console.error('解析WebSocket消息失败:', e)
      }
    }
    
    this.socket.onclose = () => {
      console.log('[WebSocket] 连接已关闭')
      // 只有非手动关闭才尝试重连
      if (!this.isManualClose) {
        this.handleReconnect(onMessage, onSuccess, onError)
      }
    }
    
    this.socket.onerror = (error: Event) => {
      console.error('[WebSocket] 连接错误:', error)
      if (this.connectErrorCallback) {
        this.connectErrorCallback(error)
      }
      // 只有非手动关闭才尝试重连
      if (!this.isManualClose) {
        this.handleReconnect(onMessage, onSuccess, onError)
      }
    }
    
    return true
  }

  // 处理重连
  public handleReconnect(
    onMessage: Function,
    onSuccess?: Function,
    onError?: Function
  ): void {
    // 先检查是否还能重连
    if (this.reconnectAttempts >= this.maxReconnectAttempts) {
      console.log('[WebSocket] 重连次数已达上限')
      ElMessage.error('连接断开，请检查网络')
      this.reconnectAttempts = 0 // 重置重连次数
      return
    }
    
    // 检查用户是否仍然登录
    const userStr = localStorage.getItem('user')
    if (!userStr) {
      console.log('[WebSocket] 用户未登录，停止重连')
      this.close() // 关闭连接
      return
    }
    
    let userInfo: any
    try {
      userInfo = JSON.parse(userStr)
    } catch (e) {
      console.log('[WebSocket] 用户信息解析失败，停止重连')
      this.close()
      return
    }
    
    if (!userInfo || !userInfo.user_id) {
      console.log('[WebSocket] 用户未登录，停止重连')
      this.close() // 关闭连接
      return
    }
    
    // 记录重连尝试次数
    console.log(`[WebSocket] 尝试重连(${this.reconnectAttempts + 1}/${this.maxReconnectAttempts})`)
    
    this.reconnectTimer = setTimeout(() => {
      this.reconnectAttempts++ // 在真正重连时再增加重连次数
      this.init(onMessage, onSuccess, onError)
    }, 2000 * (this.reconnectAttempts + 1)) // 逐步增加重连间隔
  }

  // ---------------------------（收到消息）----------------------------
  private handleMessage(data: any): void {
    // 获取系统通知 store 实例
    const systemNotificationStore = useSystemNotificationStore()

    switch (data.type) {
      case WsResponseType.CONNECTION_SUCCESS:
        // 连接成功消息
        console.log('WebSocket连接成功:', data.msg)
        if (this.connectSuccessCallback) {
          this.connectSuccessCallback()
        }
        break
      case WsResponseType.CONNECTION_ERROR:
        // 错误消息处理
        ElMessage.error(data.msg || '服务器错误')
        break
      case WsResponseType.SYSTEM_NOTIFICATION:
        // 系统通知消息 添加到系统通知 store
        systemNotificationStore.handleSystemNotificationReceived(data.data)
        break
      case WsResponseType.SYSTEM_NOTIFICATION_READ_SUCCESS:
        // 接收到系统通知已读成功
        systemNotificationStore.handleSystemNotificationReadSuccess(data.notification_id)
        break
      case WsResponseType.ERROR:
        // 错误消息处理
        ElMessage.error(data.msg || '服务器错误')
        console.error(data.msg || '服务器错误')
        break
      default:
        // 错误消息处理
        ElMessage.error(data.msg || '未知的WebSocket消息类型:' + data.type)
        console.warn('', data.type)
    }

    // 调用回调函数
    if (this.messageCallback && typeof this.messageCallback === 'function') {
      this.messageCallback(data)
    }
  }

  // ---------------------------（发送消息）----------------------------
  public sendMessage(message: any): void {
    if (this.isConnected()) {
      this.socket!.send(JSON.stringify(message))
    } else {
      ElMessage.warning('连接未建立，正在尝试重连，请重试')

      // 尝试重新连接
      if (this.messageCallback) {
        this.init(this.messageCallback, this.connectSuccessCallback, this.connectErrorCallback)
      }
    }
  }

  // 注册消息回调（用于不同组件注册自己的处理逻辑）
  public registerCallback(onMessage: Function): void {
    this.messageCallback = onMessage
  }

  // 关闭连接
  public close(isManual: boolean = true): void {
    this.isManualClose = isManual // 设置手动关闭标志
    if (this.socket) {
      this.socket.close()
      this.socket = null
    }
    // 清除重连定时器
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer)
      this.reconnectTimer = null
    }
    this.reconnectAttempts = 0 // 重置重连次数
  }

  // 检查连接状态
  public isConnected(): boolean {
    return this.socket !== null && this.socket.readyState === WebSocket.OPEN
  }
  
  // 销毁实例，清理监听器
  public destroy(): void {
    // 关闭WebSocket连接
    this.close()
  }
}

// 导出单例实例
export default WebSocketManager.getInstance()